package my1024.view;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Group;
import javax.media.j3d.Texture2D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.vecmath.Point2d;
import javax.vecmath.Vector3f;

import my1024.app.Const;
import my1024.model.BoxModel;

import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.geometry.Primitive;

/**
 * minhvv, p18, IFI, TPE 01/2014 - 07/2014
 */

public class MyBox {
	public static final float BOX_SIZE = 0.1f;
	private BranchGroup bg;
	private TransformGroup tg;
	private Box renderingBox;
	private BoxModel model;

	public MyBox(BoxModel model) {
		this.model = model;
		initScene();
		addBoxToScene();
	}

	private void initScene() {
		bg = new BranchGroup();
		bg.setCapability(Group.ALLOW_CHILDREN_EXTEND);
		bg.setCapability(BranchGroup.ALLOW_DETACH);
		bg.setUserData(this);

		tg = new TransformGroup();
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

		bg.addChild(tg);
	}

	private void addBoxToScene() {
		translateToLocation();

		Appearance app = new Appearance();
		app.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
		app.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);

		applyTexture(app, model.getValue());
		renderingBox = new Box(0.1f, 0.1f, 0.1f, Primitive.GENERATE_TEXTURE_COORDS, app);
		tg.addChild(renderingBox);
	}

	public void changeBoxTexture(BoxModel newModel) {
		this.model = newModel;
		applyTexture(renderingBox.getAppearance(), model.getValue());
	}

	private void applyTexture(Appearance app, int boxValue) {
		Texture2D texture = Const.getTexture(new Integer(boxValue).toString());
		if (null != texture) {
			app.setTexture(texture);
			app.setTransparencyAttributes(
					new TransparencyAttributes(TransparencyAttributes.FASTEST, 0.1f));
		}
	}

	public void moveBox(BoxModel newModel) {
		this.model = newModel;
		translateToLocation();
	}

	private void translateToLocation() {
		Transform3D trans = new Transform3D();
		Vector3f initLocation = calculateLocation();
		// initLocation.add(new Vector3f(0.5f, 0.5f, 0.0f));
		trans.setTranslation(initLocation);
		tg.setTransform(trans);
	}

	private Vector3f calculateLocation() {
		Point2d renderLoc = model.getRenderLocation();
		float vX = (float) ((renderLoc.x + 0.5f) * Const.BOX_BOUND);
		float vY = (float) ((renderLoc.y + 0.5f) * Const.BOX_BOUND);
		return new Vector3f(vX, vY, 0);
	}

	public boolean isMatchBoxModelId(BoxModel otherModel) {
		return model.matchId(otherModel);
	}

	public BoxModel getModel() {
		return model;
	}

	public BranchGroup getScene() {
		bg.compile();
		return bg;
	}
}
